package com.hcx.poi.xssf.eventmodel;

import java.io.InputStream;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import com.hcx.excel.xlsx.SheetInfo;
import com.hcx.poi.eventmodel.SheetRowHandler;
import com.hcx.poi.xssf.eventmodel.sheethandler.SheetCellContentHandler;
import com.hcx.poi.xssf.eventmodel.sheethandler.SheetCellValueContentHandler;
import com.hcx.poi.xssf.eventmodel.sheethandler.SheetRowContentHandler;
import com.hcx.xml.sax.XmlElementContentHandler;
import com.hcx.xml.sax.XmlTool;

/**
 * xlsx 文件流处理核心类，新建对象后通过 addRowHandler 添加行处理器，<br/>
 * 通过调用 parseSheet() 方法进行 Sheet 解析。
 * @author 韩朝祥
 *
 */
public class XSSFSheetRowParser {
	private OPCPackage opcPackage;
	private SharedStringsTable sst;
	private XSSFReader xssfReader;

	private SheetRowHandler rowHandler;

	public XSSFSheetRowParser(OPCPackage opcPackage) {
		try {
			this.opcPackage = opcPackage;
			xssfReader = new XSSFReader(this.opcPackage);
			sst = xssfReader.getSharedStringsTable();
		} catch (Exception ex) {
			throw new RuntimeException("初始化 SheetRowParser 失败！", ex);
		}
	}

	public void addRowHandler(SheetRowHandler handler) {
		this.rowHandler = handler;
	}

	/**
	 * sheetRid 参见 {@link XSSFHelper} 的 getSheetInfos 方法
	 * @param sheetInfo
	 */
	public void parseSheet(SheetInfo sheetInfo) {
		try {
			InputStream sheetIn = xssfReader.getSheet(sheetInfo.getRId());
			XMLReader xmlParser = XmlTool.getXmlReader();
			
			XmlElementContentHandler contentHandler = new XmlElementContentHandler();
			
			SheetRowContentHandler rowContentHandler = new SheetRowContentHandler(rowHandler);
			SheetCellContentHandler cellContentHandler = new SheetCellContentHandler(rowContentHandler, sst);
			SheetCellValueContentHandler cellValueContentHandler = new SheetCellValueContentHandler(cellContentHandler);

			contentHandler.addElementContentHandler(rowContentHandler);
			contentHandler.addElementContentHandler(cellContentHandler);
			contentHandler.addElementContentHandler(cellValueContentHandler);
			
			xmlParser.setContentHandler(contentHandler);
			xmlParser.parse(new InputSource(sheetIn));
			sheetIn.close();
		} catch (Exception ex) {
			throw new RuntimeException("Sheet 解析失败！", ex);
		}
	}
}
